using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

namespace Microsoft.WowAddonStudio.ProjectRefactor
{
    /// <summary>
    /// Base class for IFrameXmlMerger implementations.
    /// </summary>
    public abstract class BaseFrameXmlMerger : IFrameXmlMerger
    {
		/// <summary>
		/// Initializes a new instance of the <see cref="BaseFrameXmlMerger"/> class.
		/// </summary>
		/// <param name="fileName">Name of the file.</param>
        protected BaseFrameXmlMerger(string fileName)
        {
            FileName = fileName;
        }

		/// <summary>
		/// Gets or sets the name of the file.
		/// </summary>
		/// <value>The name of the file.</value>
        public string FileName { get; set; }

        #region IFrameXmlMerger Members

		/// <summary>
		/// Merges new text into file.
		/// </summary>
		/// <param name="newXml">The new XML.</param>
        public virtual void Merge(string newXml)
        {
            if (String.IsNullOrEmpty(FileName))
                throw new ArgumentException("FileName cannot be empty!");

            if (!File.Exists(FileName))
                throw new FileNotFoundException(String.Format("File not availabe: {0}", FileName));
        }

        /// <summary>
        /// Merges the new Lua code file name into the specified FramXml file as a refernce.
        /// </summary>
        /// <param name="frameXmlPath">Path of FrameXml file.</param>
        /// <param name="luaCodeFilePath">Path of Lua code file.</param>
        public virtual void MergeFrameName(string frameXmlPath, string luaCodeFilePath)
        {
            if (String.IsNullOrEmpty(frameXmlPath))
                throw new ArgumentNullException("frameXmlPath");

            if (String.IsNullOrEmpty(luaCodeFilePath))
                throw new ArgumentNullException("luaCodeFilePath");

            if (!File.Exists(frameXmlPath))
                throw new FileNotFoundException(String.Format("File not availabe: {0}", frameXmlPath));

            if (!File.Exists(luaCodeFilePath))
                throw new FileNotFoundException(String.Format("File not availabe: {0}", luaCodeFilePath));
        }

        #endregion

        #region Proteceted Members

		/// <summary>
		/// Replaces the script file attribute.
		/// </summary>
		/// <param name="root">The root.</param>
		/// <param name="nameTable">The name table.</param>
		/// <param name="luaFileName">Name of the lua file.</param>
		/// <returns></returns>
        protected static bool ReplaceScriptFileAttribute(XElement root, XmlNameTable nameTable, string luaFileName)
        {
            bool result = false;
            // Query the XNode for <Script /> elements
            var namespaceManager = new XmlNamespaceManager(nameTable);
            namespaceManager.AddNamespace("ans", FrameXmlMergerFactory.BlizzardNamespace);

            foreach (var scriptElement in root.XPathSelectElements("//ans:Script", namespaceManager))
            {
                // Get the filename of the reference script file
                XAttribute fileAttribute = scriptElement.Attribute("file");

                // Make sure we have a 'file' attriute
                if (fileAttribute != null)
                {
                    fileAttribute.Value = luaFileName;
                    result = true;
                }
            }
            return result;
        }

        #endregion
    }
}